/**
 * Safe logging utility that prevents sensitive information leakage in production.
 *
 * Features:
 * - Automatically disabled in production environment
 * - Filters sensitive data (passwords, tokens)
 * - Provides structured logging levels
 */

type LogLevel = 'debug' | 'info' | 'warn' | 'error'

interface LogEntry {
  level: LogLevel
  message: string
  data?: unknown
  timestamp: string
}

/**
 * Sensitive field names that should be filtered from logs
 */
const SENSITIVE_FIELDS = [
  'password',
  'token',
  'access_token',
  'refresh_token',
  'authorization',
  'cookie',
  'session',
  'secret',
  'apiKey',
  'api_key',
]

/**
 * Recursively filter sensitive data from objects
 */
function sanitizeData(data: unknown): unknown {
  if (data === null || data === undefined) {
    return data
  }

  if (typeof data !== 'object') {
    return data
  }

  if (Array.isArray(data)) {
    return data.map(sanitizeData)
  }

  const sanitized: Record<string, unknown> = {}
  for (const [key, value] of Object.entries(data)) {
    const lowerKey = key.toLowerCase()
    const isSensitive = SENSITIVE_FIELDS.some(field => lowerKey.includes(field))

    if (isSensitive) {
      sanitized[key] = '***REDACTED***'
    } else if (typeof value === 'object') {
      sanitized[key] = sanitizeData(value)
    } else {
      sanitized[key] = value
    }
  }
  return sanitized
}

/**
 * Check if we're in development environment
 */
function isDevelopment(): boolean {
  return import.meta.env.DEV || import.meta.env.MODE === 'development'
}

/**
 * Format log entry for console output
 */
function formatLogEntry(entry: LogEntry): string {
  const prefix = `[${entry.level.toUpperCase()}] ${entry.timestamp}`
  return entry.data
    ? `${prefix} ${entry.message}`
    : `${prefix} ${entry.message}`
}

/**
 * Core logging function
 */
function log(level: LogLevel, message: string, data?: unknown): void {
  const timestamp = new Date().toISOString()

  const entry: LogEntry = {
    level,
    message,
    data: data ? sanitizeData(data) : undefined,
    timestamp,
  }

  // Only log in development environment
  if (!isDevelopment() && level === 'debug') {
    return
  }

  const formattedMessage = formatLogEntry(entry)

  switch (level) {
    case 'debug':
      if (isDevelopment()) {
        // eslint-disable-next-line no-console
        console.log(formattedMessage, entry.data || '')
      }
      break
    case 'info':
      // eslint-disable-next-line no-console
      console.info(formattedMessage, entry.data || '')
      break
    case 'warn':
      // eslint-disable-next-line no-console
      console.warn(formattedMessage, entry.data || '')
      break
    case 'error':
      // eslint-disable-next-line no-console
      console.error(formattedMessage, entry.data || '')
      break
  }
}

/**
 * Safe logger instance
 */
export const logger = {
  /**
   * Debug level - only in development
   * @example logger.debug('User login attempt', { username: 'admin' })
   */
  debug(message: string, data?: unknown): void {
    log('debug', message, data)
  },

  /**
   * Info level - visible in all environments (but sanitized)
   * @example logger.info('User logged in successfully', { userId: 123 })
   */
  info(message: string, data?: unknown): void {
    log('info', message, data)
  },

  /**
   * Warning level - for non-critical issues
   * @example logger.warn('API response slow', { duration: 3000 })
   */
  warn(message: string, data?: unknown): void {
    log('warn', message, data)
  },

  /**
   * Error level - for errors and exceptions
   * @example logger.error('API request failed', { error: e.message })
   */
  error(message: string, data?: unknown): void {
    log('error', message, data)
  },
}

/**
 * Export sanitize function for testing
 */
export { sanitizeData }
